#include "epoll_op.h"
//#include "task_mgr.h"
#include <pthread.h>
#include <fcntl.h>

extern int g_epollfd;

typedef struct _thread_argc{
    void *fd;
    char *data;
} thread_argc;


struct CLIENT_INFO
{
	char ipaddr[128];
	int  port;
};

#define FILE_BUF_SIZE 1024

void * data_process(void *argc)
{
	int nread;
    int bufsize=512;
    //char request_header[512];
    char buf[bufsize];
    memset(buf,0,sizeof(buf));
    //memset(request_header,0,sizeof(request_header));

	thread_argc *ta = (thread_argc *)argc;
	struct epollfd_priv *priv = (struct epollfd_priv *)ta;//->fd;
	int fd = ta->fd;
    REQ_HEADER req_header;
	
    int ret = getReqHeader(fd,&req_header);
    if(ret < 0)
    {
        printf("get request head error\n");
        close(fd);
        return NULL;
    }
    
    int length=req_header.length;
    int totalsize=0;
    
    char *recvdata=(char*)malloc(length*sizeof(char)+1);
    memset(recvdata,0,sizeof(length*sizeof(char))+1);

    while(totalsize < length)
    {
        nread = read(fd,buf,bufsize);
        if (nread == -1)
        {
            perror("read error:");
            close(fd);
            delete_event(g_epollfd,priv,EPOLLIN);
        }
        else if (nread == 0)
        {
            fprintf(stderr,"client close.\n");
            close(fd);
            delete_event(g_epollfd,priv,EPOLLIN);
        }
        else
        {
            
            //strcat(recvdata,buf);
            memcpy(recvdata+totalsize,buf,nread);
            totalsize += nread;
        }

    }
    //修改描述符对应的事件，由读改为写
    modify_event(g_epollfd,priv,EPOLLOUT);
    struct sockaddr_in sa;
    socklen_t len = sizeof(sa);
    if(!getpeername(fd, (struct sockaddr *)&sa, &len))
    {
        printf( "对方IP：%s ", inet_ntoa(sa.sin_addr));
        printf( "对方PORT：%d ", ntohs(sa.sin_port));
    }
    //printf("read message is : %s",buf);
    switch(req_header.method){
        case PUSH_FILE :
            //create_client_data_file(fd_priv,recvdata); //fd传递指针地址
            saveRecData(priv,&req_header,recvdata);
            break;
        case GET_LIST :
            getFileList(priv,&req_header);
            break;
        case GET_RESULT :
            break;
    }
    
    

}

int worker_process(void *fd_priv, char * data)
{
	char file_path[128] = {0};
	//sprintf(file_path, "/var/emu-%s-%d",user_info.userid,task_id);

    pthread_t tid;

	thread_argc *thread_data = (thread_argc *)malloc(sizeof(thread_argc));
	memset(thread_data,0,sizeof(thread_argc));
	//memcpy(thread_data, &ta , sizeof(thread_argc) );
	thread_data->fd = ((struct epollfd_priv*)fd_priv)->fd;
	thread_data->data = data;

	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	
    int err = pthread_create(&tid, NULL, data_process, (void *)thread_data);
    if (err != 0)
    {
        perror("pthread_create\n");
        return err;
    }
    
    return SUCCESS;
}

/* 
static int send_to_user_result(void *fd, char *result_path)
{
	int file_p,buf_len,nbytes;
	char len_head[32]={0};
	off_t file_len;
	char *buf;	
	if((file_p = open(result_path,O_RDONLY)) == -1)	
	{		
		perror("open file error on send_file\n");		
		return 0;
	}
	file_len = lseek(file_p,0,SEEK_END);
	if(file_len == 0)	
	{		
		perror("file_len is zero!\n");		
		close(file_p);		
		return 0;	
	}
	else if(file_len < FILE_BUF_SIZE)
		buf_len = file_len ;	
	else 		
		buf_len = FILE_BUF_SIZE;	
	lseek(file_p,0,SEEK_SET);
	if(NULL == (buf = (char *)malloc(buf_len)))	
	{		
		printf("out of memory in send_file\n");		
		close(file_p);		
		return 0;
	}

	memset(buf,0,buf_len);
	
	sprintf(len_head,"Length:%d\n\r\n\r\n",(int)file_len);
	struct epollfd_priv *fd_priv = (struct epollfd_priv *)fd;
	send_to_user_cb(fd_priv,len_head);

	while((nbytes = read(file_p,buf,buf_len)) != -1)	
	{		
		send_to_user_cb(fd_priv,buf);
		file_len -= nbytes;	
		memset(buf,0,buf_len);	
		if(file_len <= 0)			
			goto SUCC;	
	}
	
SUCC:
	close(file_p);	
	free(buf);	
	if(nbytes == -1)	
	{		
		send_to_user_cb(fd_priv,"\0");
		return -1;	
	}	
	return 0;
	
}

static int create_emu_task(struct EMU_TASK *task, 
								  struct CLIENT_USER_INFO st_user_info, int task_id,
								  struct epollfd_priv * client_id, char *file_path, char *result_path)
{
	memset(task, 0, sizeof(struct EMU_TASK));
	strcpy(task->st_user_info.userid,st_user_info.userid);
	strcpy(task->st_user_info.password,st_user_info.password);
	task->task_id = task_id; 
	task->client_id = client_id;
	strcpy(task->file_path, file_path);
	strcpy(task->result_path, result_path);
	task->e_task_status = WAITING;
	task->send_result_cb = send_to_user_result;
	return 0;	
}

int get_time_str(void)
{
	time_t rawtime;  
    struct tm *ptminfo;  
  
    time(&rawtime);  
    ptminfo = localtime(&rawtime); 
	char tmp[128] = {0};
    sprintf(tmp,"%02d%02d%02d%02d%02d%02d",  
            ptminfo->tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday,  
            ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);  
    return atoi(tmp);  
}

int get_client_info(int fd, struct CLIENT_INFO *info)
{
	
	struct sockaddr_in sa;
	socklen_t  len = sizeof(sa);
	if(!getpeername(fd, (struct sockaddr *)&sa, &len))
	{
		strcpy(info->ipaddr,inet_ntoa(sa.sin_addr));
		info->port = ntohs(sa.sin_port);
		return 0;
	}
	return -1;
}


void * data_process(void *argc)
{
    FILE * fp=NULL;
    int rev=0,task_id;
    struct EMU_TASK task;
    struct CLIENT_INFO info;
    struct CLIENT_USER_INFO user_info;

    thread_argc *ta = (thread_argc *)argc;
	struct epollfd_priv *priv = (struct epollfd_priv *)ta->fd;
	
	char file_path[128] = {0};
	char result_path[128] = {0};

    rev = get_client_info(priv->fd, &info);
	if(rev < 0)
	{
		printf("return rev=%d\n",rev);
		return NULL;
	}
    strcpy(user_info.userid ,info.ipaddr);
	strcpy(user_info.password, "");
    task_id = get_time_str();

	sprintf(file_path, "/var/emu-%s-%d",user_info.userid,task_id);
	sprintf(result_path, "/var/emu-%s-%d-result",user_info.userid,task_id);
	//sprintf(file_path, "emu-%s-%d",user_info.userid,task_id);
    
	create_emu_task(&task, user_info , task_id, priv , file_path, result_path);

	
        
    fp=fopen(file_path,"w+");
    if(fp == NULL)
    {
        printf("open file failed!\n");
        return NULL;
    }

    fwrite(ta->data,strlen(ta->data),1,fp);
    fclose(fp);

	rev = add_emu_task(&task, HANDLE_TAIL);
	printf("add_emu_task rev=%d\n",rev);

	if(ta)
	{
		if(ta->data)
			free(ta->data);
		free(ta);
		ta = NULL;
	}
	
	return NULL;
}
*/
int create_client_data_file(void *fd_priv, char * data)
{
	char file_path[128] = {0};
	//sprintf(file_path, "/var/emu-%s-%d",user_info.userid,task_id);

	/* 
    pthread_t tid;

	thread_argc *thread_data = (thread_argc *)malloc(sizeof(thread_argc));
	memset(thread_data,0,sizeof(thread_argc));
	//memcpy(thread_data, &ta , sizeof(thread_argc) );
	thread_data->fd = fd_priv;
	thread_data->data = data;

	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	
    int err = pthread_create(&tid, NULL, data_process, (void *)thread_data);
    if (err != 0)
    {
        perror("pthread_create\n");
        return err;
    }
    */
    return SUCCESS;
}
